package com.apobates.jforum.grief.aurl.executor;

import com.apobates.jforum.grief.aurl.core.AUrlMeta;
import com.apobates.jforum.grief.aurl.core.AUrlMetaBuilder;
import com.apobates.jforum.grief.aurl.spring.ObjectUtils;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 查询参数的编辑执行器
 */
public final class ClipParameterExecutor extends AUrlMetaExecutor<AUrlMetaActionRecord> {
    private final Set<AUrlMetaActionRecord> actionRecords;
    private final AUrlMeta localIns;
    public ClipParameterExecutor(AUrlMeta rawMeta){
        super(rawMeta);
        this.actionRecords = new HashSet<>();
        this.localIns = rawMeta.clone();
    }

    private ClipParameterExecutor(AUrlMeta rawMeta, Set<AUrlMetaActionRecord> actionRecords){
        super(rawMeta);
        this.actionRecords = new HashSet<>(actionRecords);
        this.localIns = rawMeta.clone();
    }

    private ClipParameterExecutor reset(String action, String param, Collection<String> paramValues){
        this.actionRecords.add(new AUrlMetaActionRecord(action, param, paramValues));
        return new ClipParameterExecutor(localIns, actionRecords);
    }
    /**
     * 增加查询参数
     * @param name 参数名称. 例: product
     * @param values 参数值列表
     * @return
     */
    public ClipParameterExecutor add(String name, Object... values){
        Objects.requireNonNull(localIns);

        Collection<String> addPV = new ArrayList<>();
        if (!ObjectUtils.isEmpty(values)) {
            for (Object value : values) {
                String valueAsString = ObjectUtils.getQueryParamValue(value);
                addPV.add(valueAsString);
            }
        }
        if(!addPV.isEmpty()) {
            if(localIns.getQueryParams().containsKey(name)){
                localIns.getQueryParams().get(name).addAll(addPV);
                return this.reset("append", name, addPV);
            }else{
                localIns.getQueryParams().put(name, new ArrayList<>(addPV));
                return this.reset("add", name, addPV);
            }
        }
        return this;
    }

    /**
     * 删除查询参数
     * @param name 参数名称. 例: product
     * @return
     */
    public ClipParameterExecutor delete(String name){
        Objects.requireNonNull(localIns);
        if(!localIns.getQueryParams().containsKey(name)){
            return this;
        }
        Collection<String> delPV = localIns.getQueryParams().remove(name);
        return this.reset("delete", name, delPV);
    }

    /**
     * 替换查询参数
     * @param name 参数名称. 例: product
     * @param values 参数值列表
     * @return
     */
    public ClipParameterExecutor replace(String name, Object... values){
        Objects.requireNonNull(localIns);
        if(!localIns.getQueryParams().containsKey(name) || ObjectUtils.isEmpty(values)){
            return this;
        }
        List<String> collect = Arrays.stream(values).map(ObjectUtils::getQueryParamValue).collect(Collectors.toList());
        Collection<String> replacePV = localIns.getQueryParams().put(name, collect);
        return this.reset("replace", name, replacePV);
    }

    @Override
    public Set<AUrlMetaActionRecord> getActionRecords() {
        return actionRecords;
    }

    @Override
    public AUrlMetaBuilder getBuilder() {
        return AUrlMetaBuilder.getInstance()
                .scheme(localIns.getScheme())
                .host(localIns.getHost())
                .userInfo(localIns.getUserInfo())
                .port(localIns.getPort())
                .path(localIns.getPath())
                .query(localIns.getQuery())
                .fragment(localIns.getFragment());
    }

}
